<?php
/*
+-----------------------------------------------------------------------------+
| $Id: bwupload.class.php 2009-09-15 11:48:33Z Bleakwind $
| Upload file
| Copyright (c) 2003-2010 Bleakwind (www.weaverdream.com)
| http://www.weaverdream.com/
| Release under the GNU Lesser General Public License Version 3 (LGPLv3):
|   http://www.gnu.org/licenses/lgpl.html
+-----------------------------------------------------------------------------+
*/

class bwupload
{

    var $max_file_size   = 2097152; // byte
    var $allow_type      = array('.png','.jpg','.gif');

    var $admin_email     = "Administrator";
    var $halt_on_error   = "jump"; // "yes" (halt with message),
                                   // "no" (halt with no message),
                                   // "report" (go on with message),
                                   // "jump" (go on with no message),


    var $name_length     = 40;
    var $proceed         = array();
    var $error_msg;
    var $lang_msg;

    function bwupload()
    {
        $this->lang_msg = array(
            '0'             => "Upload class: The file uploaded success...",
            '1'             => "Upload class: The uploaded file exceeds the php max filesize directive...",
            '2'             => "Upload class: The uploaded file exceeds the HTML form max filesize directive...",
            '3'             => "Upload class: The uploaded file was only partially uploaded...",
            '4'             => "Upload class: No file was uploaded...",
            '6'             => "Upload class: Missing a temporary folder...",
            '7'             => "Upload class: Failed to write file to disk...",
            '8'             => "Upload class: File upload stopped by extension...",
            'invalid'       => "Upload class: Invalid upload...",
            'error_size'    => "Upload class: Error upload file size...",
            'error_type'    => "Upload class: Error upload file type...",
            'upload_failed' => "Upload class: Upload file failed...",
            'error_empty'   => "Upload class: No input for file or file too big...",
        );
    }

    function set_size($size)
    {
        $this->max_file_size = $size;
    }

    function set_type($type)
    {
        if (!is_array($type)) {
            $this->allow_type = preg_split("/[\s,|]+/", $type);
        }
    }

    function set_name_length($name_length)
    {
        if (preg_match("/^[0-9]{1,2}$/",$name_length)) {
            $this->name_length = $name_length;
        }
    }

    function check_dir($dir)
    {
        $dir = substr($dir,-1) != "/" ? $dir."/" : $dir;
        //if (!is_dir($dir)){
        if (!file_exists($dir)){
            $this->make_dir($dir);
        }
        return $dir;
    }

    // Mkdir use recursive
    function make_dir($dir, $mode = 0755, $recursive = true) {
        if ( is_dir($dir) || $dir === "/" ){
            return TRUE;
        }
        if ($recursive === true) {
            if ( $this->make_dir(dirname($dir), $mode, $recursive) ){
                return mkdir($dir, $mode);
            }
        }else{
            if ( is_dir(dirname($dir)) ) {
                return mkdir($dir, $mode);
            }
        }
        return FALSE;
    }

    function delete_file($filename, $dir)
    {
        $dir = $this->check_dir($dir);
        if (file_exists($dir.$filename)) {
            if (unlink($dir.$filename)) {
                return true;
            }
        }
        return false;
    }

    function return_lenstr($str)
    {
        $str_len = strlen($str);
        for ($i=0;$i<$this->name_length;$i++) {
            $str_new .= $str{$i%$str_len};
        }
        return $str_new;
    }

    function upload_file($target_dir, $upload_name = "")
    {
        $this->proceed = array();
        $this->check_dir($target_dir);

        if (!empty($upload_name)) {
            $upload[$upload_name] = $_FILES[$upload_name];
        } else {
            $upload = $_FILES;
        }

        if (empty($upload)) {
            $this->halt($this->lang_msg['error_empty']);
            return false;
        } else {
            foreach ($upload as $name => $array) {

                if (is_array($array['name'])){
                    foreach($array['error'] as $key => $value){
                        if (is_uploaded_file($array['tmp_name'][$key])) {

                            $name_temp   = strtolower(str_replace(' ', '', $array['name'][$key]));
                            preg_match("/([^\/.]*)\.[^\/.]*$/", $name_temp, $name_primal); $name_primal = $name_primal[1];
                            preg_match("/[^\/.]*(\.[^\/.]*)$/", $name_temp, $name_extend); $name_extend = $name_extend[1];

                            if ($array['size'][$key] > $this->max_file_size) {
                                $this->proceed[$name][$key]['succeed']     = "2";
                                $this->proceed[$name][$key]['name']        = $array['name'][$key];
                                $this->proceed[$name][$key]['type']        = $array['type'][$key];
                                $this->proceed[$name][$key]['tmp_name']    = $array['tmp_name'][$key];
                                $this->proceed[$name][$key]['error']       = $this->halt($this->lang_msg['error_size']);
                                $this->proceed[$name][$key]['size']        = $array['size'][$key];
                            } elseif (!in_array($name_extend, $this->allow_type)) {
                                $this->proceed[$name][$key]['succeed']     = "2";
                                $this->proceed[$name][$key]['name']        = $array['name'][$key];
                                $this->proceed[$name][$key]['type']        = $array['type'][$key];
                                $this->proceed[$name][$key]['tmp_name']    = $array['tmp_name'][$key];
                                $this->proceed[$name][$key]['error']       = $this->halt($this->lang_msg['error_type']);
                                $this->proceed[$name][$key]['size']        = $array['size'][$key];
                            } else {
                                $filename       = "";
                                $file_notexists = false;
                                while($file_notexists === false){
                                    $name_base = $this->return_lenstr(sha1($name_primal.microtime()));
                                    $filename = $name_base.$name_extend;
                                    if(!file_exists($target_dir.$filename)) {
                                        $file_notexists = true;
                                    }
                                }
                                if (!move_uploaded_file($array['tmp_name'][$key], $target_dir.$filename)) {
                                    $this->proceed[$name][$key]['succeed']     = "2";
                                    $this->proceed[$name][$key]['name']        = $array['name'][$key];
                                    $this->proceed[$name][$key]['type']        = $array['type'][$key];
                                    $this->proceed[$name][$key]['tmp_name']    = $array['tmp_name'][$key];
                                    $this->proceed[$name][$key]['error']       = $this->halt($this->lang_msg['upload_failed']);
                                    $this->proceed[$name][$key]['size']        = $array['size'][$key];
                                } else {
                                    $this->proceed[$name][$key]['succeed']     = "1";
                                    $this->proceed[$name][$key]['result_name'] = $filename;
                                    $this->proceed[$name][$key]['name']        = $array['name'][$key];
                                    $this->proceed[$name][$key]['type']        = $array['type'][$key];
                                    $this->proceed[$name][$key]['tmp_name']    = $array['tmp_name'][$key];
                                    $this->proceed[$name][$key]['error']       = $this->halt($this->lang_msg[$array['error'][$key]]);
                                    $this->proceed[$name][$key]['size']        = $array['size'][$key];
                                }
                            }
                        } else {
                            $this->proceed[$name][$key]['succeed']     = "2";
                            $this->proceed[$name][$key]['name']        = $array['name'][$key];
                            $this->proceed[$name][$key]['type']        = $array['type'][$key];
                            $this->proceed[$name][$key]['tmp_name']    = $array['tmp_name'][$key];
                            $this->proceed[$name][$key]['error']       = $this->halt($this->lang_msg['invalid']);
                            $this->proceed[$name][$key]['size']        = $array['size'][$key];
                        }
                    }
                }else{
                    if (is_uploaded_file($array['tmp_name'])) {

                        $name_temp   = strtolower(str_replace(' ', '', $array['name']));
                        preg_match("/([^\/.]*)\.[^\/.]*$/", $name_temp, $name_primal); $name_primal = $name_primal[1];
                        preg_match("/[^\/.]*(\.[^\/.]*)$/", $name_temp, $name_extend); $name_extend = $name_extend[1];

                        if ($array['size'] > $this->max_file_size) {
                            $this->proceed[$name]['succeed']     = "2";
                            $this->proceed[$name]['name']        = $array['name'];
                            $this->proceed[$name]['type']        = $array['type'];
                            $this->proceed[$name]['tmp_name']    = $array['tmp_name'];
                            $this->proceed[$name]['error']       = $this->halt($this->lang_msg['error_size']);
                            $this->proceed[$name]['size']        = $array['size'];
                        } elseif (!in_array($name_extend, $this->allow_type)) {
                            $this->proceed[$name]['succeed']     = "2";
                            $this->proceed[$name]['name']        = $array['name'];
                            $this->proceed[$name]['type']        = $array['type'];
                            $this->proceed[$name]['tmp_name']    = $array['tmp_name'];
                            $this->proceed[$name]['error']       = $this->halt($this->lang_msg['error_type']);
                            $this->proceed[$name]['size']        = $array['size'];
                        } else {
                            $filename       = "";
                            $file_notexists = false;
                            while($file_notexists === false){
                                $name_base = $this->return_lenstr(sha1($name_primal.microtime()));
                                $filename = $name_base.$name_extend;
                                if(!file_exists($target_dir.$filename)) {
                                    $file_notexists = true;
                                }
                            }
                            if (!move_uploaded_file($array['tmp_name'], $target_dir.$filename)) {
                                $this->proceed[$name]['succeed']     = "2";
                                $this->proceed[$name]['name']        = $array['name'];
                                $this->proceed[$name]['type']        = $array['type'];
                                $this->proceed[$name]['tmp_name']    = $array['tmp_name'];
                                $this->proceed[$name]['error']       = $this->halt($this->lang_msg['upload_failed']);
                                $this->proceed[$name]['size']        = $array['size'];
                            } else {
                                $this->proceed[$name]['succeed']     = "1";
                                $this->proceed[$name]['result_name'] = $filename;
                                $this->proceed[$name]['name']        = $array['name'];
                                $this->proceed[$name]['type']        = $array['type'];
                                $this->proceed[$name]['tmp_name']    = $array['tmp_name'];
                                $this->proceed[$name]['error']       = $this->halt($this->lang_msg[$array['error']]);
                                $this->proceed[$name]['size']        = $array['size'];
                            }
                        }
                    } else {
                        $this->proceed[$name]['succeed']     = "2";
                        $this->proceed[$name]['name']        = $array['name'];
                        $this->proceed[$name]['type']        = $array['type'];
                        $this->proceed[$name]['tmp_name']    = $array['tmp_name'];
                        $this->proceed[$name]['error']       = $this->halt($this->lang_msg['invalid']);
                        $this->proceed[$name]['size']        = $array['size'];
                    }
                }
            }
            return $this->proceed;
        }
    }

    function file_rename($source_dir, $filename, $newname)
    {
        $source_dir = $this->check_dir($source_dir);
        if (rename($source_dir.$filename, $newname)) {
            return true;
        } else {
            return false;
        }
    }

    // private: error handling
    function halt($msg)
    {
        $this->error_msg = $msg;
        if ($this->halt_on_error == "yes" || $this->halt_on_error == "report") {
            printf("<div style='font-family:sans-serif;font-size: 11px;'><b>Weaverdream info:</b> Upload Error</div>\n");
            printf("<div style='width:600px;padding: 3px;background-color:#D6DFF7;border:#1151BF 1px solid;font-family:sans-serif;font-size: 11px;'>\n");
            printf("<b>Page:</b> ".$_SERVER['PHP_SELF']."<br>\n");
            printf("<b>Upload error:</b> %s <br>\n", $msg);
            printf("</div>\n");
            printf("<div style='font-family:sans-serif;font-size: 11px;'>You can try to <a href='javascript:location.reload()' target='_self'><font color='#1151BF' style='text-decoration:none;'>refresh</font></a> the page, if this doesn't fix the error, please contact <font color='#1151BF'>".$this->admin_email."</font> and report the error message.</div>\n");
        }
        if ( $this->halt_on_error == "yes" ) {
            exit("<div style='font-family:sans-serif;font-size: 11px;'>Upload halted.</div>\n");
        }elseif( $this->halt_on_error == "no" ){
            exit();
        }
        return $this->error_msg;
    }
}
?>